package com.vrv.vap.baseline.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.vrv.vap.baseline.config.ExcelTemplateConfig;
import com.vrv.vap.baseline.converter.LongStringConverter;
import com.vrv.vap.baseline.handler.CellWriteHandler;
import com.vrv.vap.baseline.util.FileOperationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.List;

public abstract class AbstractExcelExportService<T> {
    private static final Logger log = LoggerFactory.getLogger(AbstractExcelExportService.class);
    protected final FileOperationUtil fileOperationUtil;
    protected final ExcelTemplateConfig excelTemplateConfig;
    protected final String templateKey;
    protected int maxCellLength;
    protected String excelFileName;
    protected String sheetName;

    protected AbstractExcelExportService(FileOperationUtil fileOperationUtil, ExcelTemplateConfig excelTemplateConfig, String templateKey) {
        this.fileOperationUtil = fileOperationUtil;
        this.excelTemplateConfig = excelTemplateConfig;
        this.templateKey = templateKey;
        ExcelTemplateConfig.TemplateProperties template = excelTemplateConfig.getTemplateByKey(templateKey);
        this.maxCellLength = template.getMaxCellLength();
        this.excelFileName = template.getFileName();
        this.sheetName = template.getSheetName();
    }

    protected abstract List<T> getAllData();

    protected abstract void processData(List<T> dataList, String format) throws IOException;

    protected abstract Class<T> getEntityClass();

    protected ExcelWriter createExcelWriter(String excelFilePath) {
        try {
            return EasyExcel.write(excelFilePath)
                    .registerConverter(new LongStringConverter())
                    .registerWriteHandler(new CellWriteHandler())
                    .build();
        } catch (Exception e) {
            log.error("创建ExcelWriter失败: {}", excelFilePath, e);
            throw new RuntimeException("创建ExcelWriter失败", e);
        }
    }

    protected String exportToExcel(List<T> list, String format) {
        String fDir = fileOperationUtil.createChildDir(templateKey, format);
        String excelFilePath = fDir + File.separator + excelFileName;

        try (ExcelWriter excelWriter = createExcelWriter(excelFilePath)) {
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
            WriteTable writeTable = EasyExcel.writerTable(0)
                    .head(getEntityClass())
                    .needHead(Boolean.TRUE)
                    .build();
            excelWriter.write(list, writeSheet, writeTable);
        } catch (Exception e) {
            log.error("导出Excel文件失败: {}", excelFilePath, e);
            throw new RuntimeException("导出Excel文件失败", e);
        }
        return fDir;
    }

    public String exportZip() throws IOException {
        String format = fileOperationUtil.getCurrentTimeFormat();
        List<T> list = getAllData();
        try {
            processData(list, format);
            String excelFile = exportToExcel(list, format);
            String zipFile = fileOperationUtil.createZipFile(excelFile);
//            fileOperationUtil.cleanupOldFiles(7);
            return zipFile;
        } catch (Exception e) {
            log.error("导出数据失败", e);
            throw new RuntimeException("导出数据失败", e);
        }
    }
}